
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	
</body>
<script type="text/javascript">
	



	    //异步同步
	    //异步和同步的区别:

		//	异步不会阻塞程序的执行，  同一时间可以做多个件事情：  双向六车道  双向八车道
		//	同步会阻塞程序的执行:    同一时间只能做在一个时间片段只能做同一件事情   独木桥
	    //

		// 事件循环机制  event loop
		// JavaScript 语言的一大特点就是单线程，也就是说，同一个时间只能做一件事。为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为，
		// 防止主线程的不阻塞，Event Loop 的方案应用而生。Event Loop 包含两类：一类是基于 Browsing Context，一种是基于 Worker。
		// 二者的运行是独立的，也就是说，每一个 JavaScript 运行的"线程环境"都有一个独立的 Event Loop，每一个 Web Worker 也有一个独立的 Event Loop。


		//先做题：  
		//宏任务  
		//同步
		console.log('script start')		
		// 宏任务
		setTimeout(function(){
			console.log('setTimeout') 
		},0) 	
		//微任务
		async1(); 		
		//微任务
		new Promise(function(resolve,reject){
			//同步
			console.log('promise')
			for (var i = 0; i <10000; i++) {
				if (i === 10) {
					console.log("3")
				}
				i == 9999 && resolve('4')
			}
			resolve('5');
		}).then(function(val){
			console.log(val)
			//异步
			console.log('promise1')
			return Promise.resolve("6")
		}).then(function(res){
			console.log(res)
			console.log('promise2')
		})	
		async function async1(){
			//同步
			console.log('async1 start');
			await async2()
			//异步
			console.log('async1 end')
		}	
		async function async2(){
			//同步
			console.log('async2 end')
		}	
		//同步
		console.log('script end')

		// 宏任务包括：setTimeout setInterval Ajax DOM事件  script(整体代码)	I/O UI交互事件	postMessageMessage	Channel	setImmediate(Node.js 环境)
		// 微任务：Promise async/await  Object.observe	MutationObserver	process.nextTick(Node.js 环境)
		// 微任务比宏任务的执行时间要早
		// 异步和单线程
		// 异步和单线程是相辅相成的，js是一门单线程脚本语言，所以需要异步来辅助

		// 异步和同步的区别:

		// 异步不会阻塞程序的执行，
		// 同步会阻塞程序的执行，
		// 前端使用异步的场景：

		// 定时任务：setTimeout，setInverval
		// 网络请求：ajax请求，动态<img>加载
		// 事件绑定
		// 任务队列和event loop（事件循环）
		// 1）所有的同步任务都在主线程上执行，行成一个执行栈。
		// 2）除了主线程之外，还存在一个任务列队，只要异步任务有了运行结果，就在任务列队中植入一个时间标记。
		// 3）主线程完成所有任务(执行栈清空），就会读取任务列队，先执行微任务队列在执行宏任务队列。
		// 4）重复上面三步。
		// 只要主线程空了，就会读取任务列队，这就是js的运行机制，也被称为 event loop（事件循环）。




		// 知识点：
		// 考察的是事件循环和回调队列。注意以下几点：
		// Promise 优先于 setTimeout 宏任务，所以 setTimeout 回调会最后执行
		// Promise 一旦被定义就会立即执行
		// Promise 的 resolve 和 reject  是异步执行的回调。所以 resolve() 会被放到回调队列中，在主函数执行完和 setTimeout 之前调用
		// await 执行完后，会让出线程。async 标记的函数会返回一个 Promise 对象

		// 解析：
		// 首先，事件循环从宏任务（macrostack）队列开始，这个时候，宏任务队列中，只有一个 script (整体代码)任务。从宏任务队列中取出一个任务来执行。
		// 首先执行 console.log('script start')，输出 ‘script start'
		// 遇到 setTimeout 把 console.log('setTimeout') 放到 macrotask 队列中
		// 执行 aync1() 输出 ‘async1 start' 和 'async2' ,把 console.log('async1 end') 放到 micro 队列中
		// 执行到 promise ，输出 'promise1' ，把 console.log('promise2') 放到  micro 队列中
		// 执行 console.log('script end')，输出 ‘script end'
		// macrotask 执行完成会执行 microtask ，把 microtask quene 里面的 microtask 全部拿出来一次性执行完，所以会输出 'async1 end' 和 ‘promise2'
		// 开始新一轮的事件循环，去除执行一个 macrotask 执行，所以会输出 ‘setTimeout'

</script>
</html>